#include "key.h"

struct my_key_manege
{
    rt_uint8_t num;
    rt_timer_t timer;
    struct my_key *key_list[MY_KEY_LIST_MAX];
};

static struct my_key_manege key_manage;

#define MY_KEY_CALL(func,argv)\
    do{ if((func)!=RT_NULL) func(argv); }while(0)

int my_key_register(struct my_key *key)
{
    if(key->press_logic_level ==0)
    {
        rt_pin_mode(key->pin, PIN_MODE_INPUT_PULLUP);
    }else {
        rt_pin_mode(key->pin, PIN_MODE_INPUT_PULLDOWN);
    }

    key->cnt=0;
    key->event = KEY_EVENT_NONE;

    key_manage.key_list[key_manage.num++]=key;

    return 0;

}

static void my_key_scan(void *param)
{
    rt_uint8_t i;
    rt_uint16_t cnt_old;


    for(i =0;i < key_manage.num;i++ )
    {
        cnt_old = key_manage.key_list[i]->cnt;

        if(rt_pin_read(key_manage.key_list[i]->pin)==key_manage.key_list[i]->press_logic_level)
        {
            key_manage.key_list[i]->cnt ++;

            if(key_manage.key_list[i]->cnt == MY_KEY_DOWN_MS/MY_KEY_SCAN_SPACE_MS)
            {
                //rt_kprintf("KEY DOWN\n");
                key_manage.key_list[i]->event = KEY_EVENT_CLICK_DOWN;
                MY_KEY_CALL(key_manage.key_list[i]->cb,(key_manage.key_list[i]));
            }
            else if(key_manage.key_list[i]->cnt == MY_KEY_HOLD_MS/MY_KEY_SCAN_SPACE_MS)
            {
                //rt_kprintf("KEY HOLD\n");
                key_manage.key_list[i]->event = KEY_EVENT_HOLD;
                MY_KEY_CALL(key_manage.key_list[i]->cb,(key_manage.key_list[i]));
            }
            else if(key_manage.key_list[i]->cnt > MY_KEY_HOLD_MS/MY_KEY_SCAN_SPACE_MS)
            {
                //rt_kprintf("KEY HOLD CYC\n");
                key_manage.key_list[i]->event = KEY_EVENT_HOLD_CYC;
                if(key_manage.key_list[i]->hold_cyc_period && key_manage.key_list[i]->cnt%
                        (key_manage.key_list[i]->hold_cyc_period/MY_KEY_SCAN_SPACE_MS)==0)
                {
                    MY_KEY_CALL(key_manage.key_list[i]->cb,(key_manage.key_list[i]));
                }
           }

        }
        else
        {
            key_manage.key_list[i]->cnt=0;

            if(cnt_old >= MY_KEY_DOWN_MS/MY_KEY_SCAN_SPACE_MS && cnt_old < MY_KEY_HOLD_MS/MY_KEY_SCAN_SPACE_MS)
            {
                //rt_kprintf("key click up\n");
                key_manage.key_list[i]->event = KEY_EVENT_CLICK_UP;
                MY_KEY_CALL(key_manage.key_list[i]->cb,(key_manage.key_list[i]));
            }
            else if (cnt_old >= MY_KEY_HOLD_MS/MY_KEY_SCAN_SPACE_MS)
            {
                //rt_kprintf("key hold up\n");
                key_manage.key_list[i]->event = KEY_EVENT_HOLD_UP;
                MY_KEY_CALL(key_manage.key_list[i]->cb,(key_manage.key_list[i]));
            }
        }

    }

}

int my_key_start(void)
{
    if(key_manage.timer != RT_NULL)
    {
        return -1;
    }

    key_manage.timer = rt_timer_create("timer1",
            my_key_scan,
            0,
            RT_TICK_PER_SECOND * MY_KEY_SCAN_SPACE_MS / 1000,
            RT_TIMER_FLAG_PERIODIC|RT_TIMER_FLAG_SOFT_TIMER);
    if(key_manage.timer!= RT_NULL)
    {
        rt_timer_start(key_manage.timer);
    }
    return 0;
}







